/**
 * String类
 *      StringBuilder介绍 + 面试题
 *
 * 认识异常
 *      1.异常的概念与体系结构
 *      2.异常的处理
 *      3.自定义异常类
 */
public class Test {
    /**
     * 异常的处理
     *      1.防御式编程
     *          1.事前防御型
     *          2.事后认错型
     *      2.异常的抛出
     *
     * 异常的五个关键字
     * throw try catch finally throws
     */
    /**
     * 异常的捕获
     *      throws,异常的声明
     *      try-catch捕获处理
     */
    public static void main(String[] args) {
        /**
         * throws异常的声明
         *      当前方法暂时不处理异常,提醒程序员需要处理该异常
         *      语法格式:
         *      修饰符 方法名(方法参数) throws 异常类型,异常类型 {}
         *
         *  注意事项
         *      1.必须跟在方法参数后面
         *      2.声明的异常必须是Exception/Exception子类
         *      3.方法内部如果会抛出多个异常,则需要声明多个异常,使用,隔开,如果异常存在继承关系,则声明父类即可
         *      4.调用方法抛出异常时,程序员必须处理异常或者使用throws继续抛出异常
         */
    }
    public static void func(int[] array) {
        if(array == null) {
            throw new RuntimeException("数组指向为null");
        }
    }
    public static void main9(String[] args) {
        /**
         * 异常的抛出->throw
         *
         * 注意事项
         *      1.throw只能在方法内部使用
         *      2.throw抛出的错误只能是Exception或Exception的子类
         *      3.如果抛出的错误类型是RunTimeException/其子类类型,编译器会进行处理(即进行报错)
         *      4.如果抛出的是编译时异常,则必须由程序员进行处理,否则无法编译
         *      5.异常一旦抛出,后面代码就无法执行
         */
        func(null);
    }
    public static void main8(String[] args) {
        /**
         * 事后认错型:先操作,遇到问题再解决问题
         * 优点:流程代码与错误代码区分开,程序员更加关心流程,代码清晰,易于理解
         */
/*        try {
            登陆游戏();
            开始匹配();
            游戏确认();
            选择英雄();
            载入游戏画面();
        ...
        } catch (登陆游戏异常) {
            处理登陆游戏异常;
        } catch (开始匹配异常) {
            处理开始匹配异常;
        } catch (游戏确认异常) {
            处理游戏确认异常;
        } catch (选择英雄异常) {
            处理选择英雄异常;
        } catch (载入游戏画面异常) {
            处理载入游戏画面异常;
        }
        ......*/
    }
    public static void main7(String[] args) {
        /**
         * 事前防御型:在操作之前做好充分检查
         * 缺点:流程代码与错误代码混在一起,代码十分混乱难以区分
         */
//        boolean ret = false;
//        ret = 登陆游戏();
//        if (!ret) {
//            处理登陆游戏错误;
//            return;
//        }
//        ret = 开始匹配();
//        if (!ret) {
//            处理匹配错误;
//            return;
//        }
//        ret = 游戏确认();
//        if (!ret) {
//            处理游戏确认错误;
//            return;
//        }
//        ret = 选择英雄();
//        if (!ret) {
//            处理选择英雄错误;
//            return;
//        }
//        ret = 载入游戏画面();
//        if (!ret) {
//            处理载入游戏错误;
//            return;
//        }
    }
    /**
     * 异常的概念与体系
     * @param args
     *      1.异常的概念
     *      2.异常的体系结构
     *      3.异常的分类
     */
    public static void main6(String[] args) {
        /**
         * 异常的分类
         *      编译时异常:在程序编译期间遇见的异常,如使用clone方法时,必须throw异常
         *      运行时异常:在程序运行时发生的异常,如:空指针异常,算术异常...
         */
    }
    public static void main5(String[] args) {
        /**
         * 异常的体系结构
         *      Throwable -> ERROR(资源耗尽型异常,程序员必须进行介入) Exception(异常产生后,程序员通过修改代码使其继续执行)
         *      Exception->编译时异常/受查异常 运行时异常/非受查异常
         */
    }
    public static void main4(String[] args) {
        /**
         * 异常的概念
         *      程序执行过程中发生的不正常行为称为异常
         *      如:算术异常 数组越界异常 空指针异常
         */
    }
    public static void main3(String[] args) {
        /**
         * 面试题
         *      String StringBuilder StringBuffer的区别
         *          1.String内容不可修改,StringBuilder StringBuffer可以修改(因为每次都是返回this,即谁调用返回谁)
         *          2.StringBuilder StringBuffer大部分功能大同小异
         *          3.StringBuilder采取不同步处理,属于线程不安全操作,StringBuffer采取同步处理,属于线程安全操作
         */
    }
    public static void main2(String[] args) {
        /**
         * String与StringBuilder(当前都不涉及多线程)
         *      区别:String内容不可改变,StringBuilder内容可以修改
         *      转换:
         *          String->StringBuilder
         *              1.调用StringBuilder构造方法
         *              2.调用StringBuilder,append方法
         *          StringBuilder->String
         *              调用StringBuilder.toString()
         */
        //字符串转StringBuilder
        String str = "hello";

        StringBuilder stringBuilder1 = new StringBuilder(str);
        System.out.println(stringBuilder1);

        StringBuilder stringBuilder2 = new StringBuilder();
        stringBuilder2.append(str);
        System.out.println(stringBuilder2);

        //StringBuilder转字符串
        String ret = stringBuilder1.toString();
        System.out.println(ret);
    }
    public static void main1(String[] args) {
        /**
         * StringBuilder->单线程,不安全,更快
         *
         * StringBuffer->多线程,安全,耗费时间/耗费资源
         */
    }
}
